#!/usr/bin/env python
from __future__ import division

import os
import sys
import pygame
from pygame import *
import math
import random


DEBUG = 0

def readAmmoFile():
   # [(name,mass,windresit,termVol,gravity)]
   return [('potato',1,1,175,9.8),('egg',.5,.5,200,9.8),('tomato',.75,.75,100,9.8),('cow',3,1,200,9.8)]
   
class Field:
   players = []
   inFlightAmmo = []
   cur_player = 0
   lenght = 200 # in meters
   time_factor = 1
   
   def __init__(self, lenght_in = 200, localShft_in = 20):
      self.lenght = lenght_in
      self.players.append(Player(self,localShft_in,0,readAmmoFile(),45))
      self.players.append(Player(self,self.lenght - localShft_in,0,readAmmoFile(),135))
      
   def step(self,time_factor_in):
      for shot in self.inFlightAmmo:
         shot.step(time_factor_in)
         
   def getPlayer(self):
      return self.players[self.cur_player]
   
   def setNextPlayer(self):
      if self.cur_player +1 == len(self.players):
         self.cur_player = 0
      else:
         self.cur_player += 1

class Player:
   width = 20     # in meters
   height = 10    # in meters
   health = 100
   
   def __init__(self,field,xloc,yloc,ammolist,declination):
      self.position = (xloc,yloc)
      self.weapon = Weapon(self,ammolist,declination)
      self.field = field

class Ammo:
   def __init__(self, name,mass,windresit,termVol,gravity):
      self.name = name
      self.mass = mass
      self.windresit = windresit
      self.termVol = termVol
      self.gravity = gravity
      self.inflight = True
      self.rotation = 0
      self.rotationSpeed = (50-random.randrange(100)) / 50


   def step(self, time_factor):
      self.setXloc(self.xloc + (self.xspeed * time_factor))
      self.setYloc(self.yloc + (self.yspeed * time_factor))

      if self.xspeed > 0:
         xsign = 1
      elif self.xspeed < 0:
         xsign = -1
      else:
         xsign = 0

      self.setXspeed(self.xspeed - (xsign*self.windresit) * time_factor)
      self.setYspeed(self.yspeed - self.gravity* time_factor)
      if self.inflight:
         self.rotation += self.rotationSpeed

   def applyForce(self, force, angle):
      speed = force/self.mass
      rad = math.radians(angle)
      self.setXspeed(speed*math.cos(rad))
      self.setYspeed(speed*math.sin(rad))

   def setXspeed(self, xspeed):
      self.xspeed = xspeed
      if self.yloc <= 0:
         self.xspeed = 0
         self.inflight = False
      if DEBUG: print "xspeed" + str(self.yspeed)
      
   def setYspeed(self, yspeed):
      self.yspeed = yspeed
      if self.yloc <= 0:
         self.yloc = 0
         self.yspeed = 0
         self.inflight = False
      if DEBUG: print "yspeed" + str(self.yspeed)
      
   def setXloc(self, xloc):
      self.xloc = xloc
      
   def setYloc(self, Yloc):
      self.yloc = Yloc
      if self.yloc < 0:
         self.yloc = 0
         self.setYspeed(0)

   def setPosition(self, (x, y)):
      self.setXloc(x)
      self.setYloc(y)

class Weapon:
   MAXFUEL = 100
   MAXDECLINATION = 180
   MINDECLINATION = 0
   FUELINDEX = 1
   fuel_ammount = 50
   force = 0
   ammoIndx = 0   
   
   def __init__(self, player_in, ammolst_in, declination_in):
      self.declination = declination_in
      self.ammolst = ammolst_in
      self.current_ammo = self.ammolst[self.ammoIndx]
      self.player = player_in
      
   def increaseFuel(self):
      if self.fuel_ammount < 100:
         self.fuel_ammount += 1
      else:
         self.fuel_ammount = 100
      if DEBUG:
         print "increase Fuel " + str(self.fuel_ammount)
   
   def decreaseFuel(self):
      if self.fuel_ammount > 0:
         self.fuel_ammount -= 1
      else:
         self.fuel_ammount = 0
      if DEBUG:
         print "increase Fuel " + str(self.fuel_ammount)
         
   def increaseDeclination(self):
      if self.declination < 180:
         self.declination += 1
      else:
         self.declination = 180
      if DEBUG:
         print "increase Declin " + str(self.declination)
   
   def decreaseDeclination(self):
      if self.declination > 0:
         self.declination -= 1
      else:
         self.declination = 0
      if DEBUG:
            print "decrease Declin " + str(self.declination)
            
            
   def nextAmmo(self):
      if self.ammoIndx + 1 == len(self.ammolst):
         self.ammoIndx = 0
      else:
         self.ammoIndx += 1
      self.current_ammo = self.ammolst[self.ammoIndx]
   
   def prevAmmo(self):
      if self.ammoIndx - 1 < 0 :
         self.ammoIndx = len(self.ammolst) -1
      else:
         self.ammoIndx -= 1
      self.current_ammo = self.ammolst[self.ammoIndx]
   
   barrel_len = 7
   barrel_center = 0,5
   def getBarrelEnd(self):
      rad = math.radians(self.declination)
      cx, cy = self.player.position
      xOffset = cx + self.barrel_center[0] + self.barrel_len * math.cos(rad)
      yOffset = cy + self.barrel_center[1] + self.barrel_len * math.sin(rad)
      print xOffset, yOffset
      return xOffset, yOffset

   def fire(self):
      fired_ammo = Ammo(*self.ammolst[self.ammoIndx])
      fired_ammo.setPosition(self.getBarrelEnd())

      force = self.fuel_ammount * self.FUELINDEX
      fired_ammo.applyForce(force, self.declination)
      self.player.field.inFlightAmmo.append(fired_ammo)
      
      if DEBUG:
         print "len of ammoinflight " + str(len(self.player.field.inFlightAmmo))
